package gogohome.ourhome;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException; 
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.StringTokenizer;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import android.content.ServiceConnection;
import android.util.Base64;

public class rsa  
{
    public static Key generateKey(String algorithm, byte[] keyData) throws NoSuchAlgorithmException, InvalidKeySpecException {  
//    	KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);  
  //  	SecretKey key = keyGenerator.generateKey();  
    	//SecretKeySpec keySpec = new SecretKeySpec(keyData, algorithm);
    	PKCS8EncodedKeySpec spec =
    	      new PKCS8EncodedKeySpec(keyData);
    	    KeyFactory kf = KeyFactory.getInstance("RSA");

    	    return kf.generatePrivate(spec);

//    	return keySpec;  
    	}  

	
	
	 public static byte[] rsa_encode(String[] args) throws 
	 NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException
	 {
		 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");  
		 KeyPair keyPair = generator.generateKeyPair();
		 
		 PublicKey 	publicKey  = keyPair.getPublic();  
		 PrivateKey privateKey = keyPair.getPrivate();			 
		 //Key key = generateKey("RSA",)
		  String password = "mypassword";  

		         

		  byte[] passwordBytes = password.getBytes();  
		  //byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
		  byte[] publicKeyBytes = keyPair.getPrivate().getEncoded();

	  //		  byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

		 /*   
		 int len = passwordBytes.length;  

		 byte[] keyBytes = new byte[128];  

		 if (len >= 1) {  

		 System.arraycopy(passwordBytes, 0, keyBytes, 0, 8);  

		 } else {  

			 System.arraycopy(passwordBytes, 0, keyBytes, 0, len);  

		 for (int i = 0; i < (8 - len); i++) {  

		 keyBytes[len + i] = passwordBytes[i % len];  

		 }  

		 }  

		 Key key = generateKey("RSA", keyBytes); 
		 
		 //privateKey.
		 
		 Cipher cipher = Cipher.getInstance("RSA");  
//cipher.init(Cipher.ENCRYPT_MODE, publicKey);		 
		 cipher.init(Cipher.ENCRYPT_MODE, key);  
//		 cipher.init(Cipher.PUBLIC_KEY);
		 String text = "I am a boy";  
		 byte[] t0 = text.getBytes();  
		 System.out.println("P : " + ByteUtils.toHex(t0));  
		 byte[] b0 = cipher.doFinal(t0);  
		 System.out.println("E : " + ByteUtils.toHex(b0));  		             
		 cipher.init(Cipher.DECRYPT_MODE, privateKey);  
		 byte[] b1 = cipher.doFinal(b0);              
		 System.out.println("D : " + ByteUtils.toHex(b1));  
		 System.out.println(new String(b1));
		 */
		   return publicKeyBytes;
		 
	}
	 public static byte[] rsa_public_encode(byte[] PublicKEY, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException{
		 byte[] enc_data;
		 //= data.getBytes();
		 Cipher cipher = Cipher.getInstance("RSA");
		 Key key = generateKey("RSA", PublicKEY); 
		 cipher.init(Cipher.ENCRYPT_MODE,key);
		 enc_data = cipher.doFinal(data);		 		 
		 return enc_data;		 
	 }

	 static byte[] passwordEncrypt(char[] password, byte[] plaintext) throws Exception {
		    int MD5_ITERATIONS = 1000;
		    byte[] salt = new byte[8];
		    SecureRandom random = new SecureRandom();
		    random.nextBytes(salt);

		    PBEKeySpec keySpec = new PBEKeySpec(password);
		    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
		    SecretKey key = keyFactory.generateSecret(keySpec);
		    PBEParameterSpec paramSpec = new PBEParameterSpec(salt, MD5_ITERATIONS);
		    Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
		    cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

		    byte[] ciphertext = cipher.doFinal(plaintext);

		    ByteArrayOutputStream baos = new ByteArrayOutputStream();
		    baos.write(salt);
		    baos.write(ciphertext);
		    return baos.toByteArray();
		  }

	 
	 
	 
	 public static byte[] rsa_private_decode(byte[] PrivateKey, byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException{
		 byte[] dec_data;
		 //= data.getBytes();
		 Cipher cipher = Cipher.getInstance("RSA");
		 Key key = generateKey("RSA", PrivateKey); 
		 cipher.init(Cipher.DECRYPT_MODE,key);
		 dec_data = cipher.doFinal(data);		 		 
		 return dec_data;		 
	 }
	 
	 PublicKey readKeyFromFile(InputStream in) throws IOException {
		  //InputStream in =
//		    ServiceConnection.class.getResourceAsStream(keyFileName);
		  ObjectInputStream oin =
		    new ObjectInputStream(new BufferedInputStream(in));
		  try {
		    BigInteger m = (BigInteger) oin.readObject();
		    BigInteger e = (BigInteger) oin.readObject();
		    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
		    KeyFactory fact = KeyFactory.getInstance("RSA");
		    PublicKey pubKey = fact.generatePublic(keySpec);
		    return pubKey;
		  } catch (Exception e) {
		    throw new RuntimeException("Spurious serialisation error", e);
		  } finally {
		    oin.close();
		  }
		}


	 
	 
	 /*
	   public static PublicKey getPubKey(String hexPubKey)   
	   {   
	      StringTokenizer tk = new StringTokenizer(hexPubKey, " ");   
	      System.out.println(tk.countTokens());   
	      String strPubModulus = tk.nextToken();   
	      String strPubExponent = tk.nextToken();   
	      int[] intArrayPubModulus = str2int(strPubModulus, 128);   
	      int[] intArrayPubExponent = str2int(strPubExponent, 128);   
	      byte[] byteArrayPubModulus = int2byte(intArrayPubModulus);   
	      byte[] byteArrayPubExponent = int2byte(intArrayPubExponent);   
	      BigInteger bigIntPubModulus = new BigInteger(byteArrayPubModulus);   
	      BigInteger bigIntPubExponent = new BigInteger(byteArrayPubExponent);   
	      //return new RSAPubKey(bigIntPubModulus, bigIntPubExponent);   
	      return new PublicKey();
	   }  
	 */

     public static byte[] encrypt(String Buffer, String publicKey) {
         try {
                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                 X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(Base64.decode(publicKey,0));
                 Key encryptionKey = keyFactory.generatePublic(pubSpec);

                 //PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(PVK));
                 //Key encryptionKey = keyFactory.generatePrivate(privSpec);

                 Cipher rsa;
                 rsa = Cipher.getInstance("RSA");
                 rsa.init(Cipher.ENCRYPT_MODE, encryptionKey);
                 return rsa.doFinal(Buffer.getBytes());
         } catch (Exception e) {
                 e.printStackTrace();
         }
         return null;
         
 }
	 	 	 	 
	 public static String decrypt(byte[] buffer, String privateKey) {
		    try {
		            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		            PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey, 0));
		            Key decryptionKey = keyFactory.generatePrivate(privSpec);

		            //X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(Base64.decodeBase64(PUB));
		            //Key decryptionKey = keyFactory.generatePublic(pubSpec);


		            Cipher rsa;
		            rsa = Cipher.getInstance("RSA");
		            rsa.init(Cipher.DECRYPT_MODE, decryptionKey);
		            byte[] utf8 = rsa.doFinal(buffer);
		            return new String(utf8, "UTF8");
		    } catch (Exception e) {
		            e.printStackTrace();
		    }
		    return null;
		}
	 
	 
}

